/***************************************************************************
 * UTILITIES.H
 *
 * Utility Functions and Macros: Global to Application.
 *
 *  Copyright (c)1999-2002 Microsoft Corporation, All Rights Reserved
 *  Written by DSOI Office Integration, Microsoft Developer Support
 *
 *  THIS CODE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND,
 *  EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED
 *  WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
 *
 ***************************************************************************/
#ifndef DSOI_UTILITIES_H
#define DSOI_UTILITIES_H

////////////////////////////////////////////////////////////////////////
// Fixed Win32 Errors as HRESULTs
//
#define E_WIN32_BUFFERTOOSMALL    0x8007007A   //HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER)
#define E_WIN32_ACCESSVIOLATION   0x800701E7   //HRESULT_FROM_WIN32(ERROR_INVALID_ADDRESS)

////////////////////////////////////////////////////////////////////////
// String Manipulation Functions
//
STDAPI DsoConvertToUnicodeEx(LPCSTR pszMbcsString, DWORD cbMbcsLen, LPWSTR pwszUnicode, DWORD cbUniLen);
STDAPI DsoConvertToMBCSEx(LPCWSTR pwszUnicodeString, DWORD cbUniLen, LPSTR pwszMbcsString, DWORD cbMbcsLen);

STDAPI_(BSTR)   DsoConvertToBSTR(LPCSTR pszMbcsString);
STDAPI_(LPSTR)  DsoConvertToMBCS(LPCWSTR pwszUnicodeString);
STDAPI_(UINT)   DsoCompareStrings(LPCWSTR pwsz1, LPCWSTR pwsz2);

////////////////////////////////////////////////////////////////////////
// Conversion Functions (to display types as strings)...
//
STDAPI_(LPSTR) GetFormattedSize(DWORDLONG dwlSize);
STDAPI_(LPSTR) GetFormattedDate(FILETIME ftDate);

////////////////////////////////////////////////////////////////////////
// Handle Unicode file paths on OS that can support it.
//
STDAPI DsoOpenLocalFile(LPCWSTR pwzFilePath, DWORD dwAccess, DWORD dwShareMode, DWORD dwCreate, HANDLE* phFile);
STDAPI DsoGetFileFromUser(HWND hwndOwner, LPCWSTR pwzTitle, DWORD dwFlags, LPCWSTR pwszCurrentItem, BOOL fShowSave, BSTR *pbstrFile);

////////////////////////////////////////////////////////////////////////
// URL Helpers
//
STDAPI_(BOOL)    LooksLikeHTTP(LPCWSTR pwsz);
STDAPI_(LPWSTR)  ConstructUrlForFile(LPCWSTR pwszUrlParent, LPCWSTR pwszFileName);


////////////////////////////////////////////////////////////////////////
// Error Handler Helper
//
STDAPI_(void) DsoDisplayIPPError(LPCSTR pszPrefix, HRESULT hr, LPCSTR pszTitle);


////////////////////////////////////////////////////////////////////////
// Heap Allocation
//
STDAPI_(LPVOID) MemAlloc(DWORD cbSize);
STDAPI_(void)   MemFree(LPVOID ptr);

// Override new/delete to use our task allocator
// (removing CRT dependency will improve code performance and size)...
void * _cdecl operator new(size_t size);
void  _cdecl operator delete(void *ptr);


////////////////////////////////////////////////////////////////////////
// Debug macros -- Used for simple tracing in debug builds.
//
#ifdef _DEBUG

#define ASSERT(x)  if(!(x)) DebugBreak()
#define ODS(x)	OutputDebugString(x)

#define TRACE1(sz, arg1) { \
	CHAR ach[MAX_PATH]; \
	wsprintf(ach, (sz), (arg1)); \
	ODS(ach); }

#define TRACE2(sz, arg1, arg2) { \
	CHAR ach[MAX_PATH]; \
	wsprintf(ach, (sz), (arg1), (arg2)); \
	ODS(ach); }

#define TRACE3(sz, arg1, arg2, arg3) { \
	CHAR ach[MAX_PATH]; \
	wsprintf(ach, (sz), (arg1), (arg2), (arg3)); \
	ODS(ach); }

#else // !defined(_DEBUG)

#define ASSERT(x)
#define ODS(x)
#define TRACE1(sz, arg1)
#define TRACE2(sz, arg1, arg2)
#define TRACE3(sz, arg1, arg2, arg3)

#endif // (_DEBUG)


////////////////////////////////////////////////////////////////////////
// Common macros -- Used to make code more readable.
//
#define SEH_TRY           __try {
#define SEH_EXCEPT(hr)    } __except(GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION){hr = E_WIN32_ACCESSVIOLATION;}
#define SEH_EXCEPT_NULL   } __except(GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION){}
#define SEH_START_FINALLY } __finally {
#define SEH_END_FINALLY   }

#define LEAVE_LABEL(hr, str, lbl)        {ODS(str);TRACE1(" - 0x%X\n",hr);goto lbl;}
#define LEAVE_LABEL2(hr, hr2, str, lbl)  {ODS(str);TRACE2(" - 0x%X -> 0x%X\n",hr, hr2);hr=hr2;goto lbl;}
#define LEAVE(hr, str)                   LEAVE_LABEL(hr, str, leave_routine)
#define LEAVE2(hr, hr2, str)             LEAVE_LABEL2(hr, hr2, str, leave_routine)

#define LEAVE_ON_ERROR(hr, str)          if (FAILED(hr)) LEAVE_LABEL(hr, str, leave_routine)
#define LEAVE_ON_ERROR2(hr, hr2, str)    if (FAILED(hr)) LEAVE_LABEL2(hr, hr2, str, leave_routine)
#define RETURN_ON_ERROR(hr, str)         if (FAILED(hr)){ODS(str);TRACE1(" - 0x%X\n",hr); return hr; }
#define CHECK_NULL_RETURN(var, err)      if (NULL==(var)) return (err)

#define ADDREF_INTERFACE(x)              if (x) (x)->AddRef();
#define RELEASE_INTERFACE(x)             if (x) (x)->Release(); (x) = NULL;
#define FREE_MEMPOINTER(p)               if (p) {MemFree(p); p = NULL;}
//#define FREE_COTASKMEM(p)                if (p) {CoTaskMemFree(p); p = NULL;}
#define SAFE_RELEASE_INTERFACE(x)        SEH_TRY RELEASE_INTERFACE(x) SEH_EXCEPT_NULL

#define MAX_GUID_STRING     40

#endif //DSOI_UTILITIES_H